﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using Microsoft.SqlServer.Types;
using System.Data.SqlTypes;
using NUnit.Framework;

namespace StorageUnitTests.Validation
{
    using Storage;
    using Storage.EntityModels;
    using Storage.Exceptions;
    
    #region SetUp class

    /// <summary>
    /// This class contains the set up method that is executed once 
    /// before any of the fixtures contained in this namespace.
    /// </summary>
    [SetUpFixture]
    public class SetUpClass
    {
        /// <summary>
        /// This method is runned before all other tests. 
        /// It is used to get the TripLoaDbEntities.
        /// </summary>
        [SetUp]
        public void SetUpMethod()
        {
            ValidationTests.db = StorageManager.Instance.Entities;
        }
    }

    #endregion

    #region ValidationTests

    /// <summary>
    /// This class contains all the validation tests 
    /// </summary>
    [TestFixture]
    public class ValidationTests
    {
        public static TripLoaDataContext db;

        #region TestFailStageValidation

        /// <summary>
        /// Add two stages with wrong value for Ordinal field.
        /// Launch a FieldNotValidException.
        /// </summary>
        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(FieldNotValidException))]
        public void TestFailStageValidation()
        {
            Stage s1 = TestsHelper.CreateStage();
            s1.Ordinal = 1;
            Stage s2 = TestsHelper.CreateStage();
            s1.Ordinal = 3;

            db.Stages.InsertOnSubmit(s1);
            db.Stages.InsertOnSubmit(s2);
            db.SubmitChanges();
        }

        #endregion 

        #region TestSucceedStageValidation

        /// <summary>
        /// Add two stages right wrong value for Ordinal field.
        /// </summary>
        [Test]
        [Category("Validation.Succeed")]
        public void TestSucceedStageValidation()
        {
            Stage s1 = TestsHelper.CreateStage();
            s1.Ordinal = 1;
            Stage s2 = TestsHelper.CreateStage();
            s1.Ordinal = 2;

            db.Stages.InsertOnSubmit(s1);
            db.Stages.InsertOnSubmit(s2);
            db.SubmitChanges();

            var q = from stage in db.Stages
                    select stage;

            Assert.AreEqual(2, q.ToArray().Length);
        }

        #endregion 

        #region TestFailStageOrdinalValidation

        /// <summary>
        /// Add one stage with Ordinal = 0.
        /// Launch a FieldNotValidException.
        /// </summary>
        [Test]
        [Category("Validation.Succeed")]
        [ExpectedException(typeof(FieldNotValidException))]
        public void TestTestFailStageOrdinalValidation()
        {
            Stage s1 = TestsHelper.CreateStage();
            s1.Ordinal = 0;

            db.Stages.InsertOnSubmit(s1);
            db.SubmitChanges();
        }

        #endregion 

        #region TestFailDraftAccomplishedAtSameTime

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(TripValidationException))]
        public void TestFailDraftAccomplished()
        {
            Trip t = TestsHelper.CreateDraftTrip();
            t.Accomplished = true;

            db.Trips.InsertOnSubmit(t);
            db.SubmitChanges();
        }

        #endregion

        #region TestFailDraftRealBudget

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(TripValidationException))]
        public void TestFailDraftRealBudget()
        {
            Trip t = TestsHelper.CreateDraftTrip();
            t.RealBudget = 10;

            db.Trips.InsertOnSubmit(t);
            db.SubmitChanges();
        }

        #endregion

        #region TestFailDraftRealTime

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(TripValidationException))]
        public void TestFailDraftRealTime()
        {
            Trip t = TestsHelper.CreateDraftTrip();
            t.RealTime = 5;

            db.Trips.InsertOnSubmit(t);
            db.SubmitChanges();
        }

        #endregion

        #region TestFailNotAccomplishedRealTime

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(TripValidationException))]
        public void TestFailNotAccomplishedRealTime()
        {
            Trip t = TestsHelper.CreateDraftTrip();
            t.Draft = false;
            t.Accomplished = false;
            t.RealTime = 5;

            db.Trips.InsertOnSubmit(t);
            db.SubmitChanges();
        }

        #endregion

        #region TestFailNotAccomplishedRealBudget

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(TripValidationException))]
        public void TestFailNotAccomplishedRealBudget()
        {
            Trip t = TestsHelper.CreateDraftTrip();
            t.Draft = false;
            t.Accomplished = false;
            t.RealBudget = 10;

            db.Trips.InsertOnSubmit(t);
            db.SubmitChanges();
        }

        #endregion

        #region TestSucceedNotAccomplishedNotDraft

        [Test]
        [Category("Validation.Succeed")]
        public void TestSucceedNotAccomplishedNotDraft()
        {
            Trip t = TestsHelper.CreateDraftTrip();
            t.Draft = false;
            t.Accomplished = false;

            db.Trips.InsertOnSubmit(t);
            db.SubmitChanges();
        }

        #endregion

        #region TestFailWrongOrigin

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(FieldNotValidException))]
        public void TestFailWrongOrigin()
        {
            //Trip tt = TestsHelper.CreateDraftTrip();

            //db.Trips.InsertOnSubmit(tt);
            //db.SubmitChanges();

            //Stage s = TestsHelper.CreateStage();

            //s.Trip = tt;
            //s.SetPath("(1.11 2.67), (3.78 4.98)");
            //s.Origin = new Place() { MapPoint = SqlGeography.Point(70.999, 70.999, 4326) };
            //s.Destination = new Place() { MapPoint = SqlGeography.Point(3.78, 4.98, 4326) };

            //db.Stages.InsertOnSubmit(s);
            //db.SubmitChanges();
        }

        #endregion

        #region TestFailWrongDestination

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(FieldNotValidException))]
        public void TestFailWrongDestination()
        {
            //Trip tt = TestsHelper.CreateDraftTrip();

            //db.Trips.InsertOnSubmit(tt);
            //db.SubmitChanges();

            //Stage s = TestsHelper.CreateStage();

            //s.Trip = tt;
            //s.SetPath("(1.11 2.67), (3.78 4.98)");
            //s.Origin = new Place() { MapPoint = SqlGeography.Point(1.11, 2.67, 4326) };
            //s.Destination = new Place() { MapPoint = SqlGeography.Point(70.999, 70.999, 4326) };

            //db.Stages.InsertOnSubmit(s);
            //db.SubmitChanges();
        }

        #endregion

        #region TestFailWrongDestinationAndOrigin

        [Test]
        [Category("Validation.Fail")]
        [ExpectedException(typeof(FieldNotValidException))]
        public void TestFailWrongDestinationAndOrigin()
        {
            //Trip tt = TestsHelper.CreateDraftTrip();

            //db.Trips.InsertOnSubmit(tt);
            //db.SubmitChanges();

            //Stage s = TestsHelper.CreateStage();

            //s.Trip = tt;
            //s.SetPath("(1.11 2.67), (3.78 4.98), (5.67 8.997)");
            //s.Origin = new Place() { MapPoint = SqlGeography.Point(10.356, 2.67, 4326) };
            //s.Destination = new Place() { MapPoint = SqlGeography.Point(70.999, 70.999, 4326) };

            //db.Stages.InsertOnSubmit(s);
            //db.SubmitChanges();
        }

        #endregion

        #region TestSuceedRightDestinationOrigin

        [Test]
        [Category("Validation.Succeed")]
        public void TestSuceedRightDestinationOrigin()
        {
            //Trip tt = TestsHelper.CreateDraftTrip();

            //db.Trips.InsertOnSubmit(tt);
            //db.SubmitChanges();

            //Stage s = TestsHelper.CreateStage();

            //s.Trip = tt;            
            //s.SetPath("(1.11 2.67), (3.78 4.98), (5.67 8.997)");
            //s.Origin = new Place() { MapPoint = SqlGeography.Point(1.11, 2.67, 4326) };
            //s.Destination = new Place() { MapPoint = SqlGeography.Point(5.67, 8.997, 4326) };

            //db.Stages.InsertOnSubmit(s);
            //db.SubmitChanges();

            //var q = from st in db.Stages
            //        select st;

            //Stage stg = q.First();

            //Console.Out.WriteLine(stg.Path.ToString());

            //Assert.AreEqual(s, stg);
        }

        #endregion

        #region SetUp

        /// <summary>
        /// Executed before every test.
        /// </summary>
        [SetUp]
        public void SetUpMethod()
        {
            TestsHelper.CleanUpDB(db);
        }

        #endregion

    }

    #endregion
}
